package cn.sylinx.hbatis.ext.parse;

import java.util.Map;

import cn.sylinx.hbatis.exception.HbatisException;
import cn.sylinx.hbatis.ext.res.ClasspathSqlResource;
import cn.sylinx.hbatis.ext.res.ClasspathSqlResourceManager;
import cn.sylinx.hbatis.ext.res.StatementHandler;
import cn.sylinx.hbatis.kit.StrKit;
import cn.sylinx.hbatis.kit.Tuple;
import cn.sylinx.hbatis.log.GLog;

public abstract class SqlParser {

	public static Tuple parseSql(ClasspathSqlResource sqlResource, Map<String, Object> params) {
		String statement = ClasspathSqlResourceManager.getStatement(sqlResource.getSqlpath());
		if (StrKit.isBlank(statement)) {
			throw new HbatisException("SQL语句为空, 资源:" + sqlResource.getSqlpath());
		}
		return parseSql(statement, params, sqlResource.isFormat(), sqlResource.getStatementHandler());
	}

	public static Tuple parseSql(String statement, Map<String, Object> params, StatementHandler sqlHandler) {
		return parseSql(statement, params, true, sqlHandler);
	}

	public static Tuple parseSql(String statement, Map<String, Object> params) {
		return parseSql(statement, params, null);
	}

	public static Tuple parseSql(String statement, Map<String, Object> params, boolean format,
			StatementHandler sqlHandler) {

		TokenHandler handler = createWithParameterMap(params);
		GenericTokenParser gt = new GenericTokenParser(handler);
		Tuple tp = gt.parse(statement, format);

		if (sqlHandler != null) {
			String statementReplace = sqlHandler.handle(tp.getObject(0, String.class));
			GLog.debug("changed sql: " + statementReplace);
			return Tuple.apply(statementReplace, tp.get(1));
		}

		return tp;
	}

	private static TokenHandler createWithParameterMap(Map<String, Object> params) {
		TokenHandler handler = TokenHandler.create();
		handler.setParameterMap(params);
		return handler;
	}
}
